package com.ruoyi.combat.service.apprisk.impl;

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.*;
import java.util.stream.Collectors;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.thread.ThreadUtil;
import cn.hutool.crypto.digest.DigestUtil;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONUtil;
import com.ruoyi.combat.domain.apprisk.*;
import com.ruoyi.combat.mapper.apprisk.CombatAppTaskMapper;
import com.ruoyi.combat.mapper.apprisk.CombatApplicationMapper;
import com.ruoyi.combat.service.apprisk.*;
import com.ruoyi.combat.util.YuequanTask;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.constant.UserConstants;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.utils.MessageUtils;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.sign.Md5Utils;
import com.ruoyi.framework.manager.AsyncManager;
import com.ruoyi.framework.manager.factory.AsyncFactory;
import com.ruoyi.system.service.ISysConfigService;
import com.ruoyi.system.service.ISysUserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;


/**
 * 【请填写功能名称】Service业务层处理
 *
 * @author ruoyi
 * @date 2024-07-30
 */
@Service
@Slf4j
public class CombatApplicationServiceImpl implements ICombatApplicationService {
    @Autowired
    private CombatApplicationMapper combatApplicationMapper;
    @Autowired
    private ICombatPhoneService combatPhoneService;
    @Autowired
    private ICombatPhoneAppService combatPhoneAppService;
    @Autowired
    private YueQuanService yueQuanService;
    @Autowired
    private ICombatAppRiskService combatAppRiskService;

    @Autowired
    private CombatAppTaskMapper combatAppTaskMapper;

    @Value("${apk.uploadPath}")
    private String uploadPath;

    @Value("${apk.gitBashPath}")
    private String gitBashPath;
    @Value("${apk.collectSoftware}")
    private String collectSoftware;


    /**
     * 查询【请填写功能名称】
     *
     * @param appid 【请填写功能名称】主键
     * @return 【请填写功能名称】
     */
    @Override
    public CombatApplication selectCombatApplicationByAppid(Long appid) {
        return combatApplicationMapper.selectCombatApplicationByAppid(appid);
    }

    /**
     * 查询【请填写功能名称】列表
     *
     * @param combatApplication 【请填写功能名称】
     * @return 【请填写功能名称】
     */
    @Override
    public List<CombatApplication> selectCombatApplicationList(CombatApplication combatApplication) {
        List<CombatApplication> combatApplications = combatApplicationMapper.selectCombatApplicationListByType(combatApplication);
        for (CombatApplication app : combatApplications) {
            Long appid = app.getAppid();
            CombatAppRisk combatAppRisk = new CombatAppRisk();
            combatAppRisk.setAppId(appid);
            List<CombatAppRisk> combatAppRisks = combatAppRiskService.selectCombatAppRiskList(combatAppRisk);
            String type = "";
            Set<String> set = new HashSet<>();
            for (CombatAppRisk risk : combatAppRisks) {
                set.add(risk.getRiskContent());
            }
            for (String risk : set) {
                if (StringUtils.isNotEmpty(type)) {
                    type = type + "," + risk;
                } else {
                    type = risk;
                }
            }
            app.setType(type);
        }
        return combatApplications;
    }

    /**
     * 新增【请填写功能名称】
     *
     * @param combatApplication 【请填写功能名称】
     * @return 结果
     */
    @Override
    public int insertCombatApplication(CombatApplication combatApplication) {
        return combatApplicationMapper.insertCombatApplication(combatApplication);
    }


    /**
     * 修改【请填写功能名称】
     *
     * @param combatApplication 【请填写功能名称】
     * @return 结果
     */
    @Override
    public int updateCombatApplication(CombatApplication combatApplication) {
        return combatApplicationMapper.updateCombatApplication(combatApplication);
    }

    /**
     * 批量删除【请填写功能名称】
     *
     * @param appids 需要删除的【请填写功能名称】主键
     * @return 结果
     */
    @Override
    public int deleteCombatApplicationByAppids(Long[] appids) {
        return combatApplicationMapper.deleteCombatApplicationByAppids(appids);
    }

    /**
     * 删除【请填写功能名称】信息
     *
     * @param appid 【请填写功能名称】主键
     * @return 结果
     */
    @Override
    public int deleteCombatApplicationByAppid(Long appid) {
        return combatApplicationMapper.deleteCombatApplicationByAppid(appid);
    }

    @Override
    public List<CombatApplication> selectCombatAppByPhoneId(long phoneId) {
        List<CombatApplication> combatApplications = combatApplicationMapper.selectCombatAppByPhoneId(phoneId);
        Map<Long, CombatApplication> map = new HashMap<>();
        for (CombatApplication app : combatApplications) {
            Long appid = app.getAppid();
            if(map.get(appid)==null) {
                map.put(appid, app);
                CombatAppRisk combatAppRisk = new CombatAppRisk();
                combatAppRisk.setAppId(appid);
                List<CombatAppRisk> combatAppRisks = combatAppRiskService.selectCombatAppRiskList(combatAppRisk);
                String type = "";
                Set<String> set = new HashSet<>();
                for (CombatAppRisk risk : combatAppRisks) {
                    set.add(risk.getRiskContent());
                }
                for (String risk : set) {
                    if (StringUtils.isNotEmpty(type)) {
                        type = type + "," + risk;
                    } else {
                        type = risk;
                    }
                }
                app.setType(type);
                app.setCombatAppRisks(combatAppRisks);
            }
        }

        return combatApplications;
    }

    @Override
    public String uploadApp(MultipartFile file) {
        try {
            byte[] bytes = file.getBytes();
            String path = uploadPath + File.separator + "" + file.getOriginalFilename();
            FileUtil.writeBytes(bytes, path + file.getOriginalFilename());
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        return "";
    }

    /**
     * 上传apk文件
     * @param file
     * @param name
     * @param pkgname
     * @param versionName
     * @param icon
     */
    @Override
    public void addApp(MultipartFile file, String name, String pkgname, String versionName, String icon, String recordno) {
        try {

            CombatApplication combatApplication = new CombatApplication();
            combatApplication.setAppName(name);
            combatApplication.setAppPkgname(pkgname);
            combatApplication.setAppVersion(versionName);


            //检测是否已经上传过该版本的apk文件
            List<CombatApplication> combatApplications = combatApplicationMapper.selectCombatApplicationList(combatApplication);
            if (combatApplications == null || combatApplications.size() == 0) {

                byte[] bytes = file.getBytes();
//                String path = File.separator + name + File.separator + versionName + File.separator + file.getOriginalFilename();
                String path = "/" + pkgname + "/" + versionName + "/" + "app.apk";
                FileUtil.writeBytes(bytes, uploadPath + path);
                String md5Hex = DigestUtil.md5Hex(bytes);
                String sha256Hex = DigestUtil.sha256Hex(bytes);

                combatApplication.setAppIcon(icon);
                combatApplication.setAppPath(path);
                combatApplication.setAppMd5(md5Hex);
                combatApplication.setAppSha256(sha256Hex.toUpperCase());
                combatApplication.setCreateTime(new Date());
                int i = combatApplicationMapper.insertCombatApplication(combatApplication);
            } else {
                combatApplication = combatApplications.get(0);
            }

            Long appid = combatApplication.getAppid();

            LoginUser loginUser = SecurityUtils.getLoginUser();
            String phonenumber = loginUser.getUser().getPhonenumber();

            CombatPhone combatPhone = new CombatPhone();
            combatPhone.setPhoneNum(phonenumber);
//            if(StringUtils.isNotEmpty(recordno)){
//                combatPhone.setPhoneRecordno(recordno);
//            }
            Long phoneId;
            List<CombatPhone> combatPhones = combatPhoneService.selectCombatPhoneList(combatPhone);

            if (combatPhones == null || combatPhones.size() == 0) {
                return;
//                int i1 = combatPhoneService.insertCombatPhone(combatPhone);
//                phoneId = combatPhone.getPhoneId();
            } else {
                phoneId = combatPhones.get(0).getPhoneId();
            }

            CombatPhoneApp combatPhoneApp = new CombatPhoneApp();
            combatPhoneApp.setAppId(appid);
            combatPhoneApp.setPhoneId(phoneId);
            List<CombatPhoneApp> combatPhoneApps = combatPhoneAppService.selectCombatPhoneAppList(combatPhoneApp);
            if (combatPhoneApps.size() == 0) {
                combatPhoneApp.setInstallDate(new Date());
                combatPhoneAppService.insertCombatPhoneApp(combatPhoneApp);
            }

            Long userId = SecurityUtils.getUserId();
            CombatAppTask combatAppTask = new CombatAppTask();
            combatAppTask.setAppId(appid);
            combatAppTask.setUserId(userId);
            combatAppTask.setStatus("0");
            combatAppTask.setStatus1("0");
            combatAppTask.setStatus2("0");
            combatAppTask.setStatus3("0");
            combatAppTask.setCreateTime(new Date());
            combatAppTask.setPhoneId(phoneId);
            combatAppTask.setPhoneName(combatPhone.getPhoneName());
            combatAppTaskMapper.insertCombatAppTask(combatAppTask);

//            ThreadUtil.execAsync(new YuequanTask(yueQuanService, combatApplication,userId));
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public List<CombatApkCheckInfo> getAppWarnList() {
        String phonenumber = SecurityUtils.getLoginUser().getUser().getPhonenumber();
        CombatPhone combatPhone = combatPhoneService.selectCombatPhoneByPhoneNum(phonenumber);

        CombatPhoneApp combatPhoneApp = new CombatPhoneApp();
        combatPhoneApp.setPhoneId(combatPhone.getPhoneId());

        List<CombatPhoneApp> combatPhoneApps = combatPhoneAppService.selectCombatPhoneAppList(combatPhoneApp);

        List<CombatApkCheckInfo> list = new ArrayList<>();
        for (CombatPhoneApp cpa : combatPhoneApps) {
            Long appId = cpa.getAppId();
            CombatApplication combatApplication = combatApplicationMapper.selectCombatApplicationByAppid(appId);
            if (combatApplication != null) {
                CombatApkCheckInfo info = new CombatApkCheckInfo();
                info.setAppName(combatApplication.getAppName());
                info.setAppPkgname(combatApplication.getAppPkgname());
                info.setAppVersion(combatApplication.getAppVersion());
                info.setAppIcon(combatApplication.getAppIcon());
                info.setAppMd5(combatApplication.getAppMd5());
                info.setAppSha256(combatApplication.getAppSha256());
                info.setAppPath(combatApplication.getAppPath());
                CombatAppRisk combatAppRisk = new CombatAppRisk();
                combatAppRisk.setAppId(appId);
                List<CombatAppRisk> appRisks = combatAppRiskService.selectCombatAppRiskList(combatAppRisk);
                if (appRisks != null) {
                    for (CombatAppRisk appRisk : appRisks) {
                        AppRiskInfo appRiskInfo = new AppRiskInfo();
                        appRiskInfo.setRiskContent(appRisk.getRiskContent());
                        appRiskInfo.setTestime(appRisk.getTestime());
                        info.setAppRiskInfo(appRiskInfo);
                    }
                    list.add(info);
                }
            }
        }
        return list;
    }

    @Override
    public List<Map> getAppAnalyseInfo() {
        List<Map> result = new ArrayList<>();
//        短信
        Map<String, List<CombatApplication>> result1 = new HashMap<>();
//        GPS
        Map<String, List<CombatApplication>> result2 = new HashMap<>();
//        WiFi热点连接记录
        Map<String, List<CombatApplication>> result3 = new HashMap<>();
//        通讯录
        Map<String, List<CombatApplication>> result4 = new HashMap<>();
//        基站
        Map<String, List<CombatApplication>> result5 = new HashMap<>();
//        设备信息
        Map<String, List<CombatApplication>> result6 = new HashMap<>();

        String phonenumber = SecurityUtils.getLoginUser().getUser().getPhonenumber();
        CombatPhone combatPhone = combatPhoneService.selectCombatPhoneByPhoneNum(phonenumber);
        CombatPhoneApp combatPhoneApp = new CombatPhoneApp();
        combatPhoneApp.setPhoneId(combatPhone.getPhoneId());
        List<CombatPhoneApp> combatPhoneApps = combatPhoneAppService.selectCombatPhoneAppList(combatPhoneApp);
        for (CombatPhoneApp combatPhoneApp1 : combatPhoneApps) {
            Long appId = combatPhoneApp1.getAppId();

            CombatApplication combatApplication = combatApplicationMapper.selectCombatApplicationByAppid(appId);
            if(combatApplication==null){
                continue;
            }
            CombatAppRisk combatAppRisk = new CombatAppRisk();
            combatAppRisk.setAppId(appId);
            List<CombatAppRisk> combatAppRisks = combatAppRiskService.selectCombatAppRiskList(combatAppRisk);
            for (CombatAppRisk combatAppRisk1 : combatAppRisks) {
                String riskContent = combatAppRisk1.getRiskContent();
                if ("短信".equals(riskContent)) {
                    List<CombatApplication> o = result1.get(combatApplication.getAppMd5());
                    if (o == null) {
                        o = new ArrayList<>();
                        o.add(combatApplication);
                        result1.put(combatApplication.getAppMd5(), o);
                    }
                }  if ("GPS".equals(riskContent)) {
                    List<CombatApplication> o = result2.get(combatApplication.getAppMd5());
                    if (o == null) {
                        o = new ArrayList<>();
                        o.add(combatApplication);
                        result2.put(combatApplication.getAppMd5(), o);
                    }

                }  if ("Wi-Fi连接热点记录".equals(riskContent)) {
                    List<CombatApplication> o = result3.get(combatApplication.getAppMd5());
                    if (o == null) {
                        o = new ArrayList<>();
                        o.add(combatApplication);
                        result3.put(combatApplication.getAppMd5(), o);
                    }

                }  if ("通讯录".equals(riskContent)) {
                    List<CombatApplication> o = result4.get(combatApplication.getAppMd5());
                    if (o == null) {
                        o = new ArrayList<>();
                        o.add(combatApplication);
                        result4.put(combatApplication.getAppMd5(), o);
                    }

                }  if ("基站".equals(riskContent)) {
                    List<CombatApplication> o = result5.get(combatApplication.getAppMd5());
                    if (o == null) {
                        o = new ArrayList<>();
                        o.add(combatApplication);
                        result5.put(combatApplication.getAppMd5(), o);
                    }
                }  if ("设备信息".equals(riskContent)) {
                    List<CombatApplication> o = result6.get(combatApplication.getAppMd5());
                    if (o == null) {
                        o = new ArrayList<>();
                        o.add(combatApplication);
                        result6.put(combatApplication.getAppMd5(), o);
                    }
                }
            }
        }


        makeData(result, "短信", result1);
        makeData(result, "GPS", result2);
        makeData(result, "Wi-Fi连接热点记录", result3);
        makeData(result, "通讯录", result4);
        makeData(result, "基站", result5);
        makeData(result, "设备信息", result6);

        return result;
    }
    public List<Map> getAppAnalyseInfo1() {
        List<Map> result = new ArrayList<>();
        String phonenumber = SecurityUtils.getLoginUser().getUser().getPhonenumber();
        CombatPhone combatPhone = combatPhoneService.selectCombatPhoneByPhoneNum(phonenumber);
        CombatPhoneApp combatPhoneApp = new CombatPhoneApp();
        combatPhoneApp.setPhoneId(combatPhone.getPhoneId());
        List<CombatPhoneApp> combatPhoneApps = combatPhoneAppService.selectCombatPhoneAppList(combatPhoneApp);
        for (CombatPhoneApp combatPhoneApp1 : combatPhoneApps) {
            Long appId = combatPhoneApp1.getAppId();
            CombatApplication combatApplication = combatApplicationMapper.selectCombatApplicationByAppid(appId);

            CombatAppRisk combatAppRisk = new CombatAppRisk();
            combatAppRisk.setAppId(appId);
            List<CombatAppRisk> combatAppRisks = combatAppRiskService.selectCombatAppRiskList(combatAppRisk);
            if(combatAppRisks.size()>0) {
                Map bean = JSONUtil.toBean(JSONUtil.toJsonStr(combatApplication), Map.class);
                List<String> riskContentList = new ArrayList<>();
                for (CombatAppRisk combatAppRisk1 : combatAppRisks) {
                    riskContentList.add(combatAppRisk1.getRiskContent());
                }
                bean.put("riskContentList", riskContentList);
                result.add(bean);
            }
        }
        return result;
    }

    @Override
    public List<Map> getPhoneAppRiskInfo(Long phoneId) {
        return combatApplicationMapper.getPhoneAppRiskInfo(phoneId);
    }

    @Override
    public List<Map> appTypeCount() {
        return combatApplicationMapper.appTypeCount();
    }

    @Override
    public int delApp(String pkgname, String versionName) {
        CombatApplication combatApplication = new CombatApplication();
        combatApplication.setAppName(pkgname);
        combatApplication.setAppVersion(versionName);
        //检测是否已经上传过该版本的apk文件

        List<CombatApplication> combatApplications = combatApplicationMapper.selectCombatApplicationList(combatApplication);
        Long appid = 0l;
        if (combatApplications.size() > 0) {
            combatApplication = combatApplications.get(0);
            appid = combatApplication.getAppid();
        } else {
            return 0;
        }
        LoginUser loginUser = SecurityUtils.getLoginUser();
        String phonenumber = loginUser.getUser().getPhonenumber();
        CombatPhone combatPhone = new CombatPhone();
        combatPhone.setPhoneNum(phonenumber);
        List<CombatPhone> combatPhones = combatPhoneService.selectCombatPhoneList(combatPhone);
        Long phoneId = 0l;
        if (combatPhones.size() > 0) {
            phoneId = combatPhones.get(0).getPhoneId();
        }
        CombatPhoneApp combatPhoneApp = new CombatPhoneApp();
        combatPhoneApp.setPhoneId(phoneId);
        combatPhoneApp.setAppId(appid);
        List<CombatPhoneApp> combatPhoneApps = combatPhoneAppService.selectCombatPhoneAppList(combatPhoneApp);
        int n = 0;
        for (CombatPhoneApp combatPhoneApp1 : combatPhoneApps) {
            int i = combatPhoneAppService.deleteCombatPhoneAppByPhoneAppId(combatPhoneApp1.getPhoneAppId());
            n = n + i;
        }
        return n;
    }

    /**
     * 采集应用宝数据
     */
    @Override
    public void collectApp() {


        HttpUtil.get(collectSoftware);


       log.info("定时采集应用宝数据");


    }

    public void executeCMD(String command) {
//        String command = handlerCMD(commands);
        log.info("异步执行CMD命令",command);
        try {
            File file = new File(command);
            String name = file.getName();
            String cmd = "python " + name;
            ProcessBuilder processBuilder = new ProcessBuilder("cmd.exe", "/c", cmd);
            processBuilder.directory(file.getParentFile());
            processBuilder.redirectErrorStream(true);
            Process process = processBuilder.start();
            String result = new BufferedReader(new InputStreamReader(process.getInputStream())).lines().collect(Collectors.joining(System.lineSeparator()));
            log.info(result);
            process.waitFor();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    public void makeData(List<Map> result, String name, Map<String, List<CombatApplication>> map) {
        Map<String, Object> data = new HashMap<>();
        data.put("name", name);
        data.put("value", map.keySet().size());

        List<CombatApplication> list = new ArrayList<>();
        for (List<CombatApplication> value : map.values()) {
            list.addAll(value);
        }
        data.put("appList", list);
        result.add(data);
    }
}
